module exe(
    input [63:0] sext_imm,
    input aluimm,
    input [63:0] data1,
    input [63:0] data2,
    input is_jump,
    input [63:0] jump_pc,
    input [10:0] ALUControl,
    input [2:0] csr_control,
    input [63:0] csr_wdata,
    input [63:0] csr_data,

    output [63:0] data,
    output [63:0] csr_data_res,
    output write_ena

);

    wire [63:0] alu_data1;
    wire [63:0] alu_data2;
    wire [63:0] res;

    assign alu_data1 = data1;
    assign alu_data2 =  aluimm ? sext_imm : data2;
    assign csr_data_res = csr_control == 3'b100 ? csr_data :
                        (csr_control == 3'b010 ? csr_data | csr_wdata :
                        (csr_control == 3'b001 ? csr_data & csr_wdata : 64'd0));
    assign write_ena = csr_control[2] | csr_control[1] | csr_control[0];

    ALU alu(.data1(alu_data1), .data2(alu_data2), .ALUControl(ALUControl), .res(res));

    assign data = is_jump ? jump_pc + 4 : ((csr_control[0] | csr_control[1] | csr_control[2]) ? csr_data : res);

endmodule
